(defun get-window-width (window)
    (sdl2:get-window-size window))

(defun get-window-height (window)
    (second (multiple-value-list (sdl2:get-window-size window))))

(defstruct game-object
  x
  y
  width
  color
  rect)

(defun new-game-object (&key (x 0) (y 0) (width 1) (color '(0 0 0)))
    (make-game-object :x     x
                :y     y
                :width width
                :color color
                :rect  (sdl2:make-rect x y width width)))

(defun draw-game-object (g-o surface)
    (setf (sdl2:rect-x (game-object-rect g-o)) (floor (game-object-x g-o)))
    (setf (sdl2:rect-y (game-object-rect g-o)) (floor (game-object-y g-o)))
    
    (sdl2:fill-rect surface
                    (game-object-rect g-o)
                    (apply #'sdl2:map-rgb (sdl2:surface-format surface) (game-object-color g-o))))

(defun random-from-range (min max)
    (+ (random (- max min)) min))

(defun random-teleportation! (g-o w h)
    (setf (game-object-x g-o) (random-from-range 0 (- w (game-object-width g-o))))
    (setf (game-object-y g-o) (random-from-range 0 (- h (game-object-width g-o)))))

(defun move-game-object! (g-o direct &optional (distance 1))
    (case direct
      (:up    (decf (game-object-y g-o) distance))
      (:down  (incf (game-object-y g-o) distance))
      (:right (incf (game-object-x g-o) distance))
      (:left  (decf (game-object-x g-o) distance))))

(defun collision-p (a b)
    (let ((side-half-summ (/ (+ (game-object-width a)
                                (game-object-width b))
                             2)))
    (and (< (abs (- (game-object-x b)
                    (game-object-x  a)))
            side-half-summ)
         (< (abs (- (game-object-y b)
                    (game-object-y  a)))
            side-half-summ))))

(defun fill-surface (surface r g b)
    (sdl2:fill-rect surface
                    nil
                    (sdl2:map-rgb (sdl2:surface-format surface) r g b)))
     
(defparameter *width*  640)
(defparameter *height* 480)

(defun game ()
    (sdl2:with-init (:video)
        (sdl2:with-window (win :title "Съешь яблоки" :w *width* :h *height* :flags '(:shown :resizable))
            (let ((scr-sur (sdl2:get-window-surface win))
                  (apple  (new-game-object :width 32 :color '(255 0 0)))
                  (player (new-game-object :width 64 :color '(0 0 255)))
                  (direction :down)
                  (player-speed 1))
                (random-teleportation! apple
                                      (get-window-width  win)
                                      (get-window-height win))
                (sdl2:with-event-loop ()
                    (:quit () t)
                    (:keydown (:keysym keysym)
                              (setf direction
                                    (case (sdl2:scancode keysym)
                                      (:scancode-up :up)
                                      (:scancode-down :down)
                                      (:scancode-left :left)
                                      (:scancode-right :right)
                                      (t :default))))
                    (:idle ()
                           (setf scr-sur (sdl2:get-window-surface win))
                           (fill-surface scr-sur 10 160 200)
                           (draw-game-object apple  scr-sur)
                           (draw-game-object player scr-sur)
                           (when (collision-p apple player)
                               (random-teleportation! apple
                                                     (get-window-width  win)
                                                     (get-window-height win)))
                           (move-game-object! player direction player-speed)
                           

                           (sdl2:update-window win)))))))
